package com.example.demo.core.storage;

import com.example.demo.dal.mapper.TbRuleMapper;
import com.example.demo.dal.model.TbRule;
import com.example.demo.dal.model.TbRuleExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

/**
 * @author zuitu@foxmail.com
 * @date 2020/06/18
 */
@Component
public class RuleStorageMysql implements IRuleStorage {
    @Autowired
    private TbRuleMapper ruleMapper;

    @Override
    public List<TbRule> getRuleList() {
        TbRuleExample example = new TbRuleExample();
        example.setOrderByClause("result_id asc,lft desc");
        return ruleMapper.selectByExample(example);
    }

    @Override
    public Long addRoot(String name, String val) {
        TbRule rule = new TbRule();
        rule.setName(name);
        rule.setVal(val);
        rule.setResultId(System.currentTimeMillis());
        int affectRows = ruleMapper.insertSelective(rule);
        if (affectRows > 0) {
            return rule.getId();
        } else {
            return 0L;
        }
    }

    @Override
    public TbRule getParent(Long pid) {
        return ruleMapper.selectByPrimaryKey(pid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addChild(Long pid, String name, String val, String op) {
        TbRule parent = getParent(pid);

        TbRule rule = new TbRule();
        rule.setResultId(parent.getResultId());
        rule.setName(name);
        rule.setVal(val);
        rule.setOp(op);
        rule.setLvl(parent.getLvl() + 1);
        rule.setLft(parent.getRgt());
        rule.setRgt(parent.getRgt() + 1);

        TbRuleExample incrRgtExample = new TbRuleExample();
        incrRgtExample.createCriteria()
                .andResultIdEqualTo(parent.getResultId())
                .andRgtGreaterThanOrEqualTo(rule.getLft());
        ruleMapper.incrRgtByExample(2, incrRgtExample);

        TbRuleExample incrLftExample = new TbRuleExample();
        incrLftExample.createCriteria()
                .andResultIdEqualTo(parent.getResultId())
                .andLftGreaterThanOrEqualTo(rule.getRgt());
        ruleMapper.incrLftByExample(2, incrLftExample);

        int affectRows = ruleMapper.insertSelective(rule);
        if (affectRows > 0) {
            return rule.getId();
        } else {
            return 0L;
        }
    }
}
